<?php

namespace IMT\EventBundle\Services;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

use Symfony\Bundle\TwigBundle\TwigEngine;

use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Acl\Model\AclProviderInterface;
use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
use Symfony\Component\Security\Acl\Permission\MaskBuilder;
use Doctrine\ORM\EntityManager;
use IMT\EventBundle\Models\EventInterface;
use IMT\EventBundle\Models\EventManager as BaseEventManager;
use Symfony\Component\Validator\Constraint;

class EventManager extends BaseEventManager
{
    protected $em;
    protected $class;
    protected $repository;
    
    // Propriétés spécifiques
    private $templatesEvent;
    private $menuConfig;

    /**
     * Constructor
     * @param AclProviderInterface $aclProvider
     * @param SecurityContext $securityContext
     * @param Request $request
     * @param TwigEngine $templating
     * @param array $templatesBase
     * @param EntityManager $em
     * @param unknown_type $class
     * @param array $templatesEvent
     * @param array $menuConfig
     */
    public function __construct(
    		AclProviderInterface $aclProvider, 
    		SecurityContext $securityContext, 
    		Request $request,
    		TwigEngine $templating,
    		array $templatesBase,
    		EntityManager $em, 
    		$class,
    		array $templatesEvent,
    		array $menuConfig
    )
    {
        parent::__construct($aclProvider, $securityContext, $request, $templating, $templatesBase);

        $this->em = $em;
        $this->repository = $em->getRepository($class);

        $metadata = $em->getClassMetadata($class);
        $this->class = $metadata->name;
        
        // Configuration spécifique à event
        $this->templatesEvent = $templatesEvent;
        $this->menuConfig = $menuConfig;
    }
    
    /**
     * {@inheritDoc}
     */
    public function getDefaultConfig()
    {
    	$configBase = parent::getDefaultConfig();
    	
    	$configEvent = array('event' => array(
    		'templates' => array(
    			'base' => $this->templating->render($this->templatesEvent['base']),
    			'views' => $this->templating->render($this->templatesEvent['views'])
    		),
    		'menu' => $this->getDefaultMenuConfig()
    	));
    	
    	$configBase['options'] = $configEvent;
    	
    	return $configBase;
    }
    
    public function getDefaultMenuConfig()
    {
    	$configMenu = array(
    		'templates' => array(
    			'base' => $this->templating->render($this->templatesEvent['menu']['templates']['base']),
    			'item' => $this->templating->render($this->templatesEvent['menu']['templates']['item']),
    		),
    		'menuItems' => array(),
    		//'toggleSidebar'	
    	);
    	
    	//TODO: Gestion du toggleSidebar à faire
    	
    	foreach($this->menuConfig as $menuName => $itemMenuConfig)
    	{
    		if(false !== $this->securityContext->isGranted('ROLE_MENU_'.strtoupper($menuName))){ 
    			$menu = array(
    				'template' => $this->templating->render($itemMenuConfig['template']),
    				'view' => array(
    					'templates' => array(
    						'base' => $this->templating->render($itemMenuConfig['view']['templates']['base'])
    					),
    					'content' => $this->templating->render($itemMenuConfig['view']['content'])
    				)
    			);
    			
    			$configMenu['menuItems'][$menuName] = array_merge($itemMenuConfig, $menu);
    		}
    	}
    	
    	return $configMenu;
    }
    
    public function hydrateEvent(EventInterface $event, Request $request = null)
    {
    	if($request){
    		if($request->getMethod() != 'POST')
    			throw new \BadMethodCallException('Les données doivent être envoyées par la méthode POST');

    		$event->setImportance($request->request->get('imt_event_form_general_importance'));
    		$event->setTitle($request->request->get('imt_event_form_general_title'));
    		$event->setContent($request->request->get('imt_event_form_general_content'));
    		
    		$date = new \DateTime($request->request->get('imt_event_form_general_date'));
    		$dateFin = new \DateTime($request->request->get('imt_event_form_general_dateFin'));
    		if($request->request->get('imt_event_form_general_allDay')){
    			$date = new \DateTime($date->format('Y-m-d').' 00:00:00');
    			$dateFin = new \DateTime($dateFin->format('Y-m-d').' 23:59:59');
    		}
    		$event->setDate($date);
    		$event->setDateFin($dateFin);
    		
    		$event->setAllDay($request->request->get('imt_event_form_general_allDay'));
    		
    		if($request->request->get('imt_event_form_general_account')){
	    		$repo = $this->em->getRepository('IMTAccountBundle:Account');
	    		$account = $repo->findOneBy(array("id" => $request->request->get('imt_event_form_general_account')));
	    		
	    		if(!$account)
	    			throw new \NotFoundHttpException('Le compte selectionné est introuvable');
	    			
	    		$event->setAccounts(array($account));
    		}
    	} else {
    		$event->setImportance(0);
    		$event->setTitle('Evénement sans titre');
    		$event->setContent('');
    
    		$date = new \DateTime(date('Y-m-d').' 10:00:00');
    		$event->setDate($date);
    		
    		$dateFin = clone $date;
    		$dateFin->modify('+2 hour');
    		$event->setDateFin($dateFin);
    		
    		$event->setAllDay(false);
    	}
    	 
    	return $event;
    }
    
    /**
     * Modification de l'event avec option autoFlush
     *
     * @param EventInterface $event
     * @param Boolean $autoFlush (default true)
     */
    public function updateEvent(EventInterface $event, $autoFlush = true)
    {
    	$newEvent = false;
    	$user = $this->securityContext->getToken()->getUser();
    	
    	if(NULL === $event->getId()){
    		$newEvent = true;
    		
    		$event->setOwners(array($user));
    		$event->setCreaDate(new \DateTime());
    	} else if(false === $this->securityContext->isGranted('EDIT', $event)){
    		var_dump($event);
            throw new AccessDeniedException('Vous n\'avez pas les droits pour modifier cet événement');
        }
    	
    	$event->setModifDate(new \DateTime());
    	
    	$this->em->persist($event);
    	if($autoFlush){
    		$this->em->flush();
    	}
    	
    	// Mise en place de la propriété OWNER au User de l'Event  
    	if($newEvent){
    		// Création ACL
    		$objectIdentity = ObjectIdentity::fromDomainObject($event);
    		$acl = $this->aclProvider->createAcl($objectIdentity);
    		
    		// Récupération du User connecté
    		$securityIdentity = UserSecurityIdentity::fromAccount($user);
    		
    		// Application des droits OWNER sur l'Event
    		$acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER);
    		$this->aclProvider->updateAcl($acl);
    	}
    	
    	// emission de la notification
    	if($user->getGcmId()){
	    	$headers = array('Authorization:key=AIzaSyAkNpZsTtqqqDlYCwNM4yoE-5qDuqmyrWk');
	    	$data = array(
	    		'registration_id' => $user->getGcmId(),
	    		'collapse_key' => "524363324427",
	    		'data.type' => "event",
	    		'data.id' => $event->getId(),
			    'data.participation' => false,
	    	);
	    	
	    	$ch = curl_init();
	    	
	    	curl_setopt($ch, CURLOPT_URL, "https://android.googleapis.com/gcm/send");
	    	if ($headers)
	    		curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	    	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	    	curl_setopt($ch, CURLOPT_POST, true);
	    	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	    	curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
	    	
	    	$response = curl_exec($ch);
	    	$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// 	    	if (curl_errno($ch)) {
// 	    		//request failed
// 	    		return false;//probably you want to return false
// 	    	}
// 	    	if ($httpCode != 200) {
// 	    		//request failed
// 	    		return false;//probably you want to return false
// 	    	}
	    	curl_close($ch);
// 	    	return $response;
    	}
    }
    
    /**
     * {@inheritDoc}
     */
    public function deleteEvent(EventInterface $event)
    {
    	$this->em->remove($event);
    	$this->em->flush();
    }
    
    /**
     * {@inheritDoc}
     */
    public function getClass()
    {
    	return $this->class;
    }
    
    /**
     * {@inheritDoc}
     */
    public function findEventBy(array $criteria)
    {
    	return $this->repository->findOneBy($criteria);
    }
    
	/**
	 * @return the $templatesEvent
	 */
	public function getTemplatesEvent() {
		return $this->templatesEvent;
	}

	/**
	 * @return the $menuEvent
	 */
	public function getMenuEvent() {
		return $this->menuEvent;
	}

	/**
	 * @param field_type $templatesEvent
	 */
	public function setTemplatesEvent($templatesEvent) {
		$this->templatesEvent = $templatesEvent;
	}

	/**
	 * @param field_type $menuEvent
	 */
	public function setMenuEvent($menuEvent) {
		$this->menuEvent = $menuEvent;
	}

    
}